home *** CD-ROM | disk | FTP | other *** search
/ Video Toaster 4.2 / Video Toaster v4.2.iso / programs / documentation / lightwave / sdk / sample / blotch / blotch.c next >
Encoding:
C/C++ Source or Header  |  1995-07-05  |  6.7 KB  |  331 lines

  1. /*
  2.  * BLOTCH.C --  Layout Plugin Shader
  3.  *        Stick a colored spot on a surface
  4.  *
  5.  * by Allen Hastings and Arnie Cachelin
  6.  * revised by Stuart Ferguson
  7.  * last revision  6/15/95
  8.  */
  9. #include <splug.h>
  10. #include <moni.h>
  11. #include <lwran.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15.  
  16.  
  17.  
  18. /*
  19.  * HANDLER -- Instance Methods
  20.  *
  21.  * An instance is a particular set of user-set options for a plug-in
  22.  * operation.  The options for a blotch are the color tint, the center
  23.  * and radius, and a number for the softness of the blotch edges.
  24.  */
  25. typedef struct st_Blotch {
  26.     double         color[3];
  27.     double         center[3];
  28.     double         radius;
  29.     double         softness;
  30.     double         r2, piOverR;
  31. } Blotch;
  32.  
  33.  
  34. /*
  35.  * The create function allocates a blotch struct and returns its
  36.  * pointer as the instance.  Note that "Blotch *" is used throughout
  37.  * instead of "LWInstance".  This works since a LWInstance type is
  38.  * a generic pointer and can be safely replaced with any specific
  39.  * pointer type.  Instance variables are initialized to some default
  40.  * values.
  41.  */
  42.     XCALL_(static LWInstance)
  43. Create (
  44.     LWError            *err)
  45. {
  46.     Blotch            *inst;
  47.  
  48.     XCALL_INIT;
  49.  
  50.     inst = malloc (sizeof (Blotch));
  51.     if (!inst)
  52.         return NULL;
  53.  
  54.     inst->color[0] = 0.4;
  55.     inst->color[1] = 0.0;
  56.     inst->color[2] = 0.8;
  57.  
  58.     inst->center[0] = inst->center[1] = inst->center[2] = 0.0;
  59.     inst->radius    = 1.0;
  60.     inst->softness  = 0.5;
  61.  
  62.     return inst;
  63. }
  64.  
  65.  
  66. /*
  67.  * Destroy frees the blotch instance memory.
  68.  */
  69.     XCALL_(static void)
  70. Destroy (
  71.     Blotch            *inst)
  72. {
  73.     XCALL_INIT;
  74.     free (inst);
  75. }
  76.  
  77.  
  78. /*
  79.  * Copy simply moves the data settings from one blotch struct to
  80.  * another.
  81.  */
  82.     XCALL_(static LWError)
  83. Copy (
  84.     Blotch            *from,
  85.     Blotch            *to)
  86. {
  87.     XCALL_INIT;
  88.  
  89.     *to = *from;
  90.     return (NULL);
  91. }
  92.  
  93.  
  94. /*
  95.  * Load and save.
  96.  */
  97.     XCALL_(static LWError)
  98. Load (
  99.     Blotch            *inst,
  100.     const LWLoadState    *lState)
  101. {
  102.     XCALL_INIT;
  103.     return (NULL);
  104. }
  105.  
  106.     XCALL_(LWError)
  107. Save (
  108.     Blotch            *inst,
  109.     const LWSaveState    *sState)
  110. {
  111.     XCALL_INIT;
  112.     return (NULL);
  113. }
  114.  
  115.  
  116. /*
  117.  * INIT and CLEANUP
  118.  *
  119.  * The host calls these callbacks for each shader instance just before
  120.  * and just after rendering.  This is the place to do any precalculation
  121.  * to speed up the rendering of an instance.
  122.  */
  123.     XCALL_(static LWError)
  124. Init (
  125.     Blotch            *inst)
  126. {
  127.     XCALL_INIT;
  128.  
  129.     inst->r2      = inst->radius * inst->radius;
  130.     inst->piOverR = 3.1416 / inst->radius;
  131.  
  132.     return (NULL);
  133. }
  134.  
  135.     XCALL_(static void)
  136. Cleanup (
  137.     Blotch            *inst)
  138. {
  139.     XCALL_INIT;
  140. }
  141.  
  142.  
  143. /*
  144.  * NEWTIME
  145.  *
  146.  * The host calls this callback whenever a different timestep will be
  147.  * being rendered.  It is called once at the start of a frame and more
  148.  * times during the frame if the frame requires includes multiple
  149.  * times (like in motion blur or field-rendering).
  150.  */
  151.     XCALL_(static LWError)
  152. NewTime (
  153.     Blotch            *inst,
  154.     LWFrame             f,
  155.     LWTime             t)
  156. {
  157.     XCALL_INIT;
  158.     return (NULL);
  159. }
  160.  
  161.  
  162. /*
  163.  * FLAGS
  164.  *
  165.  * The host calls the flags function to find out some information about
  166.  * this shader instance.  Since all blotches will alter the color of
  167.  * a surface but nothing else, the shader color bit is returned.
  168.  */
  169.     XCALL_(static unsigned int)
  170. Flags (
  171.     Blotch            *inst)
  172. {
  173.     XCALL_INIT;
  174.     return (LWSHF_COLOR);
  175. }
  176.  
  177.  
  178. /*
  179.  * EVALUATE
  180.  *
  181.  * This is the guts of the shader.  It is called for each spot that needs
  182.  * to be colored with this shader in the final image.  The shaderAccess
  183.  * struct contains info about the spot and some values may be modified
  184.  * by the shader according to what bits were returned in the flags
  185.  * callback.
  186.  *
  187.  * The blotch shader will compute the distance of this point to the center
  188.  * of the blotch and blend some of the blotch color with the color already
  189.  * computed for that spot.
  190.  */
  191.     XCALL_(static void)
  192. Evaluate (
  193.     Blotch            *inst,
  194.     ShaderAccess        *sa)
  195. {
  196.     double             d, r2, a;
  197.     int             i;
  198.  
  199.     XCALL_INIT;
  200.  
  201.     /*
  202.      * Compute the distance from the center of the blotch to the spot
  203.      * in object coordinates.  Exit early if the spot is clearly
  204.      * outside the blotch radius.
  205.      */
  206.     r2 = 0;
  207.     for (i = 0; i < 3; i++) {
  208.         d = sa->oPos[i] - inst->center[i];
  209.         d = d * d;
  210.         if (d > inst->r2)
  211.             return;
  212.  
  213.         r2 += d;
  214.     }
  215.     if (r2 > inst->r2)
  216.         return;
  217.  
  218.     d = sqrt (r2);
  219.  
  220.     /*
  221.      * Using the distance in 'd', compute where this spot falls in
  222.      * blotch's soft edge.  The blotch is given by a cosine density
  223.      * function scaled by the softness factor.  Where the density is
  224.      * greater than 1.0, it clips.
  225.      */
  226.     d = cos (d * inst->piOverR) * inst->softness;
  227.     if (d > 1.0)
  228.         d = 1.0;
  229.  
  230.     /*
  231.      * Finally, blend the blotch color into the existing color using
  232.      * the computed density.
  233.      */
  234.     a = 1.0 - d;
  235.     for (i = 0; i < 3; i++)
  236.         sa->color[i] = sa->color[i] * a + inst->color[i] * d;
  237. }
  238.  
  239.  
  240.  
  241. /*
  242.  * ACTIVATE
  243.  *
  244.  * The activation function for shader handlers just fills in the shader
  245.  * handler fields with callbacks for this blotch shader.
  246.  */
  247.     XCALL_(static int)
  248. BlotchActivate (
  249.     long             version,
  250.     GlobalFunc        *global,
  251.     ShaderHandler        *local,
  252.     void            *serverData)
  253. {
  254.     XCALL_INIT;
  255.     if (version != 1)
  256.         return (AFUNC_BADVERSION);
  257.  
  258.     local->inst.create  = Create;
  259.     local->inst.destroy = Destroy;
  260.     local->inst.load    = Load;
  261.     local->inst.save    = Save;
  262.     local->inst.copy    = Copy;
  263.  
  264.     local->init     = Init;
  265.     local->cleanup  = Cleanup;
  266.     local->newTime  = NewTime;
  267.     local->evaluate = Evaluate;
  268.     local->flags    = Flags;
  269.  
  270.     return (AFUNC_OK);
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  * INTERFACE
  277.  *
  278.  * The interface function for a shader is actually the activation function
  279.  * of the ShaderInterface class server for this instance type.  The instance
  280.  * to be edited is passed as the local data pointer to the interface
  281.  * activation function.  This function allows the user to edit the instance.
  282.  */
  283.     XCALL_(static int)
  284. Interface (
  285.     long             version,
  286.     GlobalFunc        *global,
  287.     Blotch            *inst,
  288.     void            *serverData)
  289. {
  290.     MessageFuncs        *msg;
  291.     char             s1[100], s2[100];
  292.  
  293.     XCALL_INIT;
  294.     if (version != 1)
  295.         return (AFUNC_BADVERSION);
  296.  
  297.     msg = (*global) ("Info Messages", GFUSE_TRANSIENT);
  298.     if (!msg)
  299.         return (AFUNC_BADGLOBAL);
  300.  
  301.     /*
  302.      * Since a full user interface is beyond the scope of this sample
  303.      * plug-in, this function will just display the current settings
  304.      * of the shader.
  305.      */
  306.     sprintf (s1, "BLOTCH: center (%f, %f, %f), radius %f",
  307.          inst->center[0], inst->center[1], inst->center[2],
  308.          inst->radius);
  309.     sprintf (s2, "color (%5.3f, %5.3f, %5.3f), softness %f",
  310.          inst->color[0], inst->color[1], inst->color[2],
  311.          inst->softness);
  312.     (*msg->info) (s1, s2);
  313.  
  314.     return (AFUNC_OK);
  315. }
  316.  
  317.  
  318.  
  319. /*
  320.  * This plug-in module contains two servers -- one for the shader handler
  321.  * and one for the interface.  The blotch instance will be passed to
  322.  * this interface server since it has the same name as the handler.  These
  323.  * servers do not have to be in the same module if a render-only shader
  324.  * plug-in is required.
  325.  */
  326. ServerRecord ServerDesc[] = {
  327.     { "ShaderHandler",    "Demo_Blotch",    BlotchActivate },
  328.     { "ShaderInterface",    "Demo_Blotch",    Interface },
  329.     { NULL }
  330. };
  331.